<!--
 * @Author: Smthie Smthie@qq.com
 * @Date: 2024-05-17 18:01:37
 * @LastEditors: Smthie Smthie@qq.com
 * @LastEditTime: 2024-05-31 16:15:38
 * @FilePath: \ProtocolTool\src\renderer\src\views\OneClick\Testing\index.vue
-->
<script lang="ts" setup>
import { h } from 'vue'
import Simplebar from 'simplebar-vue'
import 'simplebar-vue/dist/simplebar.min.css'
import {
  StopOutlined,
  ArrowLeftOutlined,
  CheckCircleTwoTone,
  CloseCircleTwoTone,
  LoadingOutlined,
  MinusCircleTwoTone
} from '@ant-design/icons-vue'
import TestingImg from '@/assets/images/testing.png'
import FinishImg from '@/assets/images/finish.png'
import StopImg from '@/assets/images/stop.png'
import TestDetail from '../components/TestDetail.vue'
import useTestStore from '@/store/modules/oneClick'

const emits = defineEmits(['return'])
const activeKey = ref([])
const testStore = useTestStore()
const scrollBarRef = ref()
// 滚动条
watch(
  () => testStore.testedStepCount,
  () => {
    if (
      !activeKey.value.length &&
      testStore.testedStepCount > 5 &&
      scrollBarRef.value.scrollElement.scrollTop < 216
    ) {
      scrollBarRef.value.scrollElement.scrollTo({
        top: (testStore.testedStepCount - 5) * 40,
        left: 0,
        behavior: 'smooth'
      })
    }
  }
)
// icon路径
const iconPath = computed(() => {
  if (testStore.status === 'active') {
    return TestingImg
  } else if (testStore.status === 'finish') {
    return FinishImg
  } else {
    return StopImg
  }
})
// 测试标题
const TestTitle = computed(() => {
  if (testStore.status === 'active') {
    return '正在测试中...'
  } else if (testStore.status === 'finish') {
    return '测试已完成'
  } else {
    return '测试已取消'
  }
})
// 测试说明
const TestDesc = computed(() => {
  if (testStore.status === 'active') {
    return `正在测试 ${testStore.currentStepObj.label}
            <span class="text-color"
              >( <span class="text-success-color">${testStore.testedStepCount} </span> /
              ${testStore.stepCount} )
            </span>`
  } else if (testStore.status === 'finish') {
    if (testStore.errorStepCount) {
      return `测试已完成，共发现 <span class="text-danger-color">${testStore.errorStepCount}</span> 个异常测试项。`
    } else {
      return '测试已完成，未发现异常测试项。'
    }
  } else {
    if (testStore.errorStepCount) {
      return `测试已取消，共发现 <span class="text-danger-color">${testStore.errorStepCount}</span> 个异常测试项。`
    } else {
      return '测试已取消，暂未发现异常测试项。'
    }
  }
})
// 测试详情
const testDetailRef = ref()
const handleDetail = (i: any) => {
  testDetailRef.value.open(i)
}
// 终止测试
const handleStop = () => {
  testStore.stopTest()
}
// 返回
const handleBack = () => {
  testStore.resetTest()
  emits('return')
}
</script>

<template>
  <div class="testing">
    <div class="top unselectable">
      <div class="status" :class="{ active: testStore.status === 'active' }">
        <div ref="circle" class="circle">
          <div class="inner"></div>
        </div>
        <div class="icon">
          <img :src="iconPath" alt="" />
        </div>
      </div>
      <div class="progress">
        <div class="progress-title">
          {{ TestTitle }}
        </div>
        <a-progress
          :stroke-color="{
            from: '#108ee9',
            to: '#69C9B2'
          }"
          :percent="(testStore.testedStepCount / testStore.stepCount) * 100"
          :status="testStore.status === 'active' ? 'active' : 'normal'"
          :size="15"
          :show-info="false"
        />
        <div class="progress-desc" v-html="TestDesc"></div>
      </div>
      <div class="opera">
        <a-button
          v-if="testStore.status === 'active'"
          size="large"
          :icon="h(StopOutlined)"
          @click="handleStop"
        >
          取消
        </a-button>
        <a-button v-else size="large" :icon="h(ArrowLeftOutlined)" @click="handleBack">
          返回
        </a-button>
      </div>
    </div>
    <div class="list">
      <Simplebar ref="scrollBarRef" class="scroll">
        <a-collapse v-model:activeKey="activeKey" :bordered="false">
          <template v-if="testStore.testInfo.protocolType === 'MQTT'">
            <div class="sort command">指令测试</div>
            <a-collapse-panel
              v-for="item in testStore.commandTestQueue"
              :key="item.id - 1"
              :show-arrow="false"
              :collapsible="item.status === null ? 'disabled' : ''"
            >
              <template #header>
                <div class="item">
                  <div class="status">
                    <CheckCircleTwoTone v-if="item.status === 1" two-tone-color="#52c41a" />
                    <CloseCircleTwoTone v-else-if="item.status === -1" two-tone-color="#f5222d" />
                    <a-spin
                      v-else-if="item.status === 0"
                      :indicator="
                        h(LoadingOutlined, {
                          style: {
                            fontSize: '16px'
                          },
                          spin: true
                        })
                      "
                    />
                    <MinusCircleTwoTone v-else two-tone-color="#ccc" />
                  </div>
                  <div class="label">{{ item.label }}</div>
                  <div class="desc">{{ item.desc }}</div>
                  <div class="info">
                    <span v-if="item.status === 1" class="text-success-color">正常</span>
                    <span v-else-if="item.status === -1" class="text-danger-color">异常</span>
                    <span v-else-if="item.status === 0" class="text-info-color">检测中</span>
                    <span v-else-if="item.status === -99" class="text-warning-color"> 已取消 </span>
                  </div>
                </div>
              </template>
              <div class="detail">
                <a-steps progress-dot direction="vertical">
                  <a-step
                    v-for="i in item.items"
                    :key="i.id"
                    :title="i.label"
                    :description="i.desc"
                    :status="i.status === 99 ? 'error' : i.status === 1 ? 'wait' : 'finish'"
                    @click="i.status === 1 || handleDetail(i)"
                  />
                </a-steps>
              </div>
            </a-collapse-panel>
            <div v-if="testStore.liveTestQueue.length" class="sort live">实时测试</div>
            <a-collapse-panel
              v-for="item in testStore.liveTestQueue"
              :key="item.id + 11"
              :show-arrow="false"
              :collapsible="item.status === null ? 'disabled' : ''"
            >
              <template #header>
                <div class="item">
                  <div class="status">
                    <CheckCircleTwoTone v-if="item.status === 1" two-tone-color="#52c41a" />
                    <CloseCircleTwoTone v-else-if="item.status === -1" two-tone-color="#f5222d" />
                    <a-spin
                      v-else-if="item.status === 0"
                      :indicator="
                        h(LoadingOutlined, {
                          style: {
                            fontSize: '16px'
                          },
                          spin: true
                        })
                      "
                    />
                    <MinusCircleTwoTone v-else two-tone-color="#ccc" />
                  </div>
                  <div class="label">{{ item.label }}</div>
                  <div class="desc">{{ item.desc }}</div>
                  <div class="info">
                    <span v-if="item.status === 1" class="text-success-color">正常</span>
                    <span v-else-if="item.status === -1" class="text-danger-color">异常</span>
                    <span v-else-if="item.status === 0" class="text-info-color">检测中</span>
                    <span v-else-if="item.status === -99" class="text-warning-color"> 已取消 </span>
                  </div>
                </div>
              </template>
              <div class="detail">
                <a-steps progress-dot direction="vertical">
                  <a-step
                    v-for="i in item.items"
                    :key="i.id"
                    :title="i.label"
                    :description="i.desc"
                    :status="i.status === 99 ? 'error' : i.status === 1 ? 'wait' : 'finish'"
                    @click="i.status === 1 || handleDetail(i)"
                  />
                </a-steps>
              </div>
            </a-collapse-panel>
          </template>
          <template v-else>
            <a-collapse-panel
              v-for="item in testStore.socketTestQueue"
              :key="item.id"
              :show-arrow="false"
              :collapsible="item.status === null ? 'disabled' : ''"
            >
              <template #header>
                <div class="item">
                  <div class="status">
                    <CheckCircleTwoTone v-if="item.status === 1" two-tone-color="#52c41a" />
                    <CloseCircleTwoTone v-else-if="item.status === -1" two-tone-color="#f5222d" />
                    <a-spin
                      v-else-if="item.status === 0"
                      :indicator="
                        h(LoadingOutlined, {
                          style: {
                            fontSize: '16px'
                          },
                          spin: true
                        })
                      "
                    />
                    <MinusCircleTwoTone v-else two-tone-color="#ccc" />
                  </div>
                  <div class="label">{{ item.label }}</div>
                  <div class="desc">{{ item.desc }}</div>
                  <div class="info">
                    <span v-if="item.status === 1" class="text-success-color">正常</span>
                    <span v-else-if="item.status === -1" class="text-danger-color">异常</span>
                    <span v-else-if="item.status === 0" class="text-info-color">检测中</span>
                    <span v-else-if="item.status === -99" class="text-warning-color"> 已取消 </span>
                  </div>
                </div>
              </template>
              <div class="detail">
                <a-steps progress-dot direction="vertical">
                  <a-step
                    v-for="i in item.items"
                    :key="i.id"
                    :title="i.label"
                    :description="i.desc"
                    :status="i.status === 99 ? 'error' : i.status === 1 ? 'wait' : 'finish'"
                    @click="i.status === 1 || handleDetail(i)"
                  />
                </a-steps>
              </div>
            </a-collapse-panel>
          </template>
        </a-collapse>
      </Simplebar>
    </div>

    <TestDetail ref="testDetailRef" />
  </div>
</template>

<style lang="less" scoped>
.testing {
  position: absolute;
  width: calc(100% - 20px);

  .top {
    margin: 32px 48px 42px;
    display: flex;
    align-items: center;

    .status {
      position: relative;

      &.active {
        .circle {
          animation: spin-animation 2s linear infinite;
        }

        @keyframes spin-animation {
          to {
            transform: rotate(360deg);
          }
        }

        .icon img {
          animation: testing-animation 2s ease-in-out infinite;
        }

        @keyframes testing-animation {
          0% {
            transform: scale(1);
          }

          50% {
            opacity: 0.5;
            transform: scale(1.2) rotate(30deg);
          }

          100% {
            transform: scale(1);
          }
        }
      }

      .circle {
        background-image: linear-gradient(#266fe8 15%, rgb(0, 225, 255));
        width: 80px;
        height: 80px;
        text-align: center;
        border-radius: 40px;
        filter: blur(1px);
        box-shadow:
          0px -5px 20px 0px #266fe8,
          0px 5px 20px 0px rgb(0, 225, 255);

        .inner {
          background-color: rgb(255, 255, 255);
          width: 80px;
          height: 80px;
          border-radius: 50px;
          filter: blur(10px);
        }
      }

      .icon {
        position: absolute;
        top: 40px;
        left: 40px;
        width: 40px;
        height: 40px;
        transform: translate(-50%, -50%);

        img {
          width: 100%;
          height: 100%;
          opacity: 0.3;
        }
      }
    }

    .progress {
      flex: 1;
      margin: 0 30px;

      .progress-title {
        font-size: 18px;
        font-weight: bold;
        margin-bottom: 10px;
      }

      .progress-desc {
        font-size: 14px;
        color: #666;
      }
    }
  }

  .list {
    margin: 0 30px;

    .scroll {
      height: 340px;
    }

    .sort {
      color: #999;
      font-size: 13px;
      font-weight: bold;
      margin-bottom: 5px;
    }

    .live {
      margin-top: 15px;
    }

    .item {
      display: flex;
      height: 40px;
      padding: 0 18px;
      align-items: center;

      &:hover {
        background-color: #f5f5f5;
      }

      .status {
        width: 32px;
      }

      .label {
        width: 120px;
        font-weight: bold;
      }

      .desc {
        font-size: 14px;
        color: #999;
      }

      .info {
        margin-left: auto;
        font-size: 15px;
        color: #333;
      }
    }

    .detail {
      margin: 0 20px;
    }
  }
}

:deep(
    :where(.css-dev-only-do-not-override-16pw25h).ant-collapse
      > .ant-collapse-item
      > .ant-collapse-header
  ) {
  padding: 0;
}

:deep(:where(.css-dev-only-do-not-override-16pw25h).ant-collapse-borderless > .ant-collapse-item) {
  border-color: #eee;

  &:nth-child(10) {
    border-bottom: none;
  }
}

:deep(:where(.css-dev-only-do-not-override-16pw25h).ant-collapse) {
  background-color: transparent;
}

:deep(:where(.css-dev-only-do-not-override-16pw25h).ant-collapse-borderless) {
  background-color: transparent;
}

:deep(.ant-steps-item) {
  cursor: text;
}

:deep(.ant-steps-item-finish),
:deep(.ant-steps-item-error) {
  cursor: pointer;
}

:deep(
    :where(.css-dev-only-do-not-override-16pw25h).ant-steps
      .ant-steps-item:is(.ant-steps-item-finish)
      > .ant-steps-item-container[role='button']:hover
  ) {
  .ant-steps-item-title {
    color: inherit;
  }

  .ant-steps-item-description {
    color: rgba(0, 0, 0, 0.45);
  }
}

:deep(
    :where(.css-dev-only-do-not-override-16pw25h).ant-steps
      .ant-steps-item:is(.ant-steps-item-error)
      > .ant-steps-item-container[role='button']:hover
  ) {
  .ant-steps-item-title,
  .ant-steps-item-subtitle,
  .ant-steps-item-description {
    color: #ff4d4f;
  }
}

:deep(
    :where(.css-dev-only-do-not-override-16pw25h).ant-steps
      .ant-steps-item:is(.ant-steps-item-wait)
      > .ant-steps-item-container[role='button']:hover
  ) {
  .ant-steps-item-title,
  .ant-steps-item-subtitle,
  .ant-steps-item-description {
    color: rgba(0, 0, 0, 0.45);
  }
}

//
:deep(:where(.css-16pw25h).ant-collapse > .ant-collapse-item > .ant-collapse-header) {
  padding: 0;
}

:deep(:where(.css-16pw25h).ant-collapse-borderless > .ant-collapse-item) {
  border-color: #eee;

  &:nth-child(10) {
    border-bottom: none;
  }
}

:deep(:where(.css-16pw25h).ant-collapse) {
  background-color: transparent;
}

:deep(:where(.css-16pw25h).ant-collapse-borderless) {
  background-color: transparent;
}

:deep(.ant-steps-item) {
  cursor: text;
}

:deep(.ant-steps-item-finish),
:deep(.ant-steps-item-error) {
  cursor: pointer;
}

:deep(
    :where(.css-16pw25h).ant-steps
      .ant-steps-item:is(.ant-steps-item-finish)
      > .ant-steps-item-container[role='button']:hover
  ) {
  .ant-steps-item-title {
    color: inherit;
  }

  .ant-steps-item-description {
    color: rgba(0, 0, 0, 0.45);
  }
}

:deep(
    :where(.css-16pw25h).ant-steps
      .ant-steps-item:is(.ant-steps-item-error)
      > .ant-steps-item-container[role='button']:hover
  ) {
  .ant-steps-item-title,
  .ant-steps-item-subtitle,
  .ant-steps-item-description {
    color: #ff4d4f;
  }
}

:deep(
    :where(.css-16pw25h).ant-steps
      .ant-steps-item:is(.ant-steps-item-wait)
      > .ant-steps-item-container[role='button']:hover
  ) {
  .ant-steps-item-title,
  .ant-steps-item-subtitle,
  .ant-steps-item-description {
    color: rgba(0, 0, 0, 0.45);
  }
}
</style>
